import { app, BrowserWindow, ipcMain, shell, dialog } from 'electron';
import { createRequire } from 'node:module';
import os from 'node:os';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
import { exec } from 'node:child_process';
import { promisify } from 'node:util';
import net from 'node:net';
import https from 'node:https';
import http from 'node:http';

const require = createRequire(import.meta.url);
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const electronPrompt = require('electron-prompt');
const fs = require('node:fs').promises;
const execAsync = promisify(exec);

// The built directory structure
//
// ├─┬ dist-electron
// │ ├─┬ main
// │ │ └── index.js    > Electron-Main
// │ └─┬ preload
// │   └── index.mjs   > Preload-Scripts
// ├─┬ dist
// │ └── index.html    > Electron-Renderer
//
process.env.APP_ROOT = path.join(__dirname, '../..');

export const MAIN_DIST = path.join(process.env.APP_ROOT, 'dist-electron');
export const RENDERER_DIST = path.join(process.env.APP_ROOT, 'dist');
export const VITE_DEV_SERVER_URL = process.env.VITE_DEV_SERVER_URL;

process.env.VITE_PUBLIC = VITE_DEV_SERVER_URL
    ? path.join(process.env.APP_ROOT, 'public')
    : RENDERER_DIST;

// Disable GPU Acceleration for Windows 7
if (os.release().startsWith('6.1')) app.disableHardwareAcceleration();

// Set application name for Windows 10+ notifications
if (process.platform === 'win32') app.setAppUserModelId(app.getName());

if (!app.requestSingleInstanceLock()) {
    app.quit();
    process.exit(0);
}

let win: BrowserWindow | null = null;
const preload = path.join(__dirname, '../preload/index.mjs');
const indexHtml = path.join(RENDERER_DIST, 'index.html');

async function createWindow() {
    win = new BrowserWindow({
        title: 'Main window',
        titleBarStyle: 'hidden',
        height: 980,
        width: 1280,
        icon: path.join(process.env.VITE_PUBLIC, 'favicon.ico'),
        maximizable: true, // 允许窗口最大化
        webPreferences: {
            preload
            // Warning: Enable nodeIntegration and disable contextIsolation is not secure in production
            // nodeIntegration: true,

            // Consider using contextBridge.exposeInMainWorld
            // Read more on https://www.electronjs.org/docs/latest/tutorial/context-isolation
            // contextIsolation: true
        }
    });

    if (VITE_DEV_SERVER_URL) {
        // #298
        win.loadURL(VITE_DEV_SERVER_URL);
        // Open devTool if the app is not packaged
        win.webContents.openDevTools();
    } else {
        win.loadFile(indexHtml);
    }

    // Test actively push message to the Electron-Renderer
    win.webContents.on('did-finish-load', () => {
        win?.webContents.send('main-process-message', new Date().toLocaleString());
    });

    // Make all links open with the browser, not with the application
    win.webContents.setWindowOpenHandler(({ url }) => {
        if (url.startsWith('https:')) shell.openExternal(url);
        return { action: 'deny' };
    });
    // win.webContents.on('will-navigate', (event, url) => { }) #344
}

app.whenReady().then(createWindow);

app.on('window-all-closed', () => {
    win = null;
    if (process.platform !== 'darwin') app.quit();
});

app.on('second-instance', () => {
    if (win) {
        // Focus on the main window if the user tried to open another
        if (win.isMinimized()) win.restore();
        win.focus();
    }
});

app.on('activate', () => {
    const allWindows = BrowserWindow.getAllWindows();
    if (allWindows.length) {
        allWindows[0].focus();
    } else {
        createWindow();
    }
});

// New window example arg: new windows url
ipcMain.handle('open-win', (_, arg) => {
    const childWindow = new BrowserWindow({
        webPreferences: {
            preload,
            nodeIntegration: true,
            contextIsolation: false
        }
    });

    if (VITE_DEV_SERVER_URL) {
        childWindow.loadURL(`${VITE_DEV_SERVER_URL}#${arg}`);
    } else {
        childWindow.loadFile(indexHtml, { hash: arg });
    }
});

// 关闭客户端
ipcMain.on('close-client', () => {
    if (win) {
        win = null;
        if (process.platform !== 'darwin') {
            app.quit();
        }
    }
});

// 最小化
ipcMain.on('minimize', () => {
    if (win) {
        win.minimize();
    }
});

// 文件对话框
ipcMain.handle('open_prompt', async (_, options) => {
    return electronPrompt(options);
});

// 读取文件
ipcMain.handle('read_file', async (_, options) => {
    try {
        const data = await fs.readFile(options.path, 'utf8');
        return data;
    } catch (err: any) {
        return err;
    }
});

// 选择目录
ipcMain.handle('select_directory', async () => {
    try {
        const result = await dialog.showOpenDialog({
            properties: ['openDirectory']
        });
        return result.canceled ? null : result.filePaths[0];
    } catch (err: any) {
        return null;
    }
});

// 获取目录下的日志文件列表
ipcMain.handle('get_log_files', async (_, dirPath: string) => {
    try {
        const files = await fs.readdir(dirPath);
        const logFiles = files.filter((file: string) => file.endsWith('.log'));
        return logFiles.map((file: string) => path.join(dirPath, file));
    } catch (err: any) {
        return [];
    }
});

// 分块读取文件内容
ipcMain.handle(
    'read_file_chunked',
    async (
        _,
        options: {
            path: string;
            chunkSize?: number;
            offset?: number;
            maxLines?: number;
        }
    ) => {
        try {
            const { path, chunkSize = 1024 * 1024, offset = 0, maxLines = 1000 } = options; // 默认1MB块大小
            const stats = await fs.stat(path);
            const fileSize = stats.size;

            if (offset >= fileSize) {
                return {
                    content: '',
                    lines: [],
                    hasMore: false,
                    nextOffset: fileSize,
                    totalSize: fileSize
                };
            }

            const readSize = Math.min(chunkSize, fileSize - offset);
            const buffer = Buffer.alloc(readSize);

            const fd = await fs.open(path, 'r');
            const { bytesRead } = await fd.read(buffer, 0, readSize, offset);
            await fd.close();

            let content = buffer.subarray(0, bytesRead).toString('utf8');

            // 确保不会在行中间截断
            if (offset + bytesRead < fileSize) {
                const lastNewlineIndex = content.lastIndexOf('\n');
                if (lastNewlineIndex > -1) {
                    content = content.substring(0, lastNewlineIndex + 1);
                    bytesRead = Buffer.byteLength(content, 'utf8');
                }
            }

            const lines = content.split('\n').filter((line) => line.length > 0);

            // 限制行数以避免内存问题
            const limitedLines = lines.slice(0, maxLines);
            const actualContent = limitedLines.join('\n');

            return {
                content: actualContent,
                lines: limitedLines,
                hasMore: offset + bytesRead < fileSize || lines.length > maxLines,
                nextOffset: offset + bytesRead,
                totalSize: fileSize,
                linesCount: limitedLines.length
            };
        } catch (error) {
            console.error(':', error);
            throw error;
        }
    }
);

// 增量读取文件内容（优化版）
ipcMain.handle('read_file_incremental', async (_, options: { path: string; lastSize?: number }) => {
    try {
        const stats = await fs.stat(options.path);
        const currentSize = stats.size;

        if (options.lastSize !== undefined && currentSize > options.lastSize) {
            // 计算需要读取的大小，限制最大读取量
            const maxIncrementalSize = 5 * 1024 * 1024; // 最大5MB增量
            const readSize = Math.min(currentSize - options.lastSize, maxIncrementalSize);
            const startOffset = currentSize - readSize;

            const buffer = Buffer.alloc(readSize);
            const fd = await fs.open(options.path, 'r');
            const { bytesRead } = await fd.read(buffer, 0, readSize, startOffset);
            await fd.close();

            let content = buffer.subarray(0, bytesRead).toString('utf8');

            // 如果不是从文件开始读取，确保从完整行开始
            if (startOffset > options.lastSize) {
                const firstNewlineIndex = content.indexOf('\n');
                if (firstNewlineIndex > -1) {
                    content = content.substring(firstNewlineIndex + 1);
                }
            }

            return {
                content,
                size: currentSize,
                isIncremental: true,
                actualSize: startOffset + bytesRead
            };
        }

        return {
            content: '',
            size: currentSize,
            isIncremental: false
        };
    } catch (error) {
        console.error('增量读取文件失败:', error);
        throw error;
    }
});

// 选择 JDK 目录
ipcMain.handle('select_jdk_directory', async () => {
    try {
        const result = await dialog.showOpenDialog(win!, {
            title: '选择 JDK 目录',
            properties: ['openDirectory'],
            message: '请选择 JDK 安装目录'
        });

        if (result.canceled || result.filePaths.length === 0) {
            return null;
        }

        return result.filePaths[0];
    } catch (error) {
        console.error('Select JDK Path Error:', error);
        throw error;
    }
});

// 选择 JAR 文件
ipcMain.handle('select_jar_file', async () => {
    try {
        const result = await dialog.showOpenDialog(win!, {
            title: '选择 JAR 文件',
            properties: ['openFile'],
            filters: [
                { name: 'JAR 文件', extensions: ['jar'] },
                { name: '所有文件', extensions: ['*'] }
            ],
            message: '请选择要运行的 JAR 文件'
        });

        if (result.canceled || result.filePaths.length === 0) {
            return null;
        }

        return result.filePaths[0];
    } catch (error) {
        console.error('Choose JAR File failed:', error);
        throw error;
    }
});

// 验证 JDK 路径
ipcMain.handle('verify_jdk_path', async (_, jdkPath: string) => {
    try {
        // 构建 java 可执行文件路径
        const javaExecutable =
            process.platform === 'win32'
                ? path.join(jdkPath, 'bin', 'java.exe')
                : path.join(jdkPath, 'bin', 'java');

        // 检查 java 可执行文件是否存在
        try {
            await fs.access(javaExecutable);
        } catch {
            return {
                success: false,
                message: 'Java 可执行文件不存在',
                version: null
            };
        }

        // 执行 java --version 命令
        const { stdout, stderr } = await execAsync(`"${javaExecutable}" --version`);

        // 解析版本信息
        const output = stdout || stderr;
        const versionMatch =
            output.match(/java (\d+(?:\.\d+)*)/i) || output.match(/openjdk (\d+(?:\.\d+)*)/i);
        const version = versionMatch ? versionMatch[1] : 'Unknown';

        return {
            success: true,
            message: 'JDK 验证成功',
            version: version,
            output: output.trim()
        };
    } catch (error: any) {
        console.error('verify JDK Path failed:', error);
        return {
            success: false,
            message: `JDK 验证失败: ${error.message}`,
            version: null
        };
    }
});

// 验证 JAR 文件
ipcMain.handle('verify_jar_file', async (_, jarPath: string) => {
    try {
        console.log('verify_jar_file: ', jarPath);
        // 检查文件是否存在
        const stats = await fs.stat(jarPath);

        if (!stats.isFile()) {
            return {
                success: false,
                message: '选择的不是文件'
            };
        }

        // 检查文件扩展名
        const ext = path.extname(jarPath).toLowerCase();
        if (ext !== '.jar') {
            return {
                success: false,
                message: '选择的文件不是 JAR 格式'
            };
        }

        // 获取文件信息
        const fileName = path.basename(jarPath);
        const fileSize = stats.size;

        return {
            success: true,
            message: 'JAR 文件验证成功',
            fileName: fileName,
            fileSize: fileSize,
            filePath: jarPath
        };
    } catch (error: any) {
        return {
            success: false,
            message: `JAR 文件验证失败: ${error.message}`
        };
    }
});

// 读取文件头部内容（用于初始加载）
ipcMain.handle('read_file_head', async (_, options: { path: string; lines?: number }) => {
    const { path, lines = 1000 } = options;
    const stats = await fs.stat(path);
    const fileSize = stats.size;

    if (fileSize === 0) {
        return { content: '', lines: [], totalSize: 0, hasMore: false };
    }

    // 如果 lines 为 -1，读取整个文件
    if (lines === -1) {
        const content = await fs.readFile(path, 'utf8');
        const allLines = content.split('\n').filter((line) => line.length > 0);

        return {
            content: allLines.join('\n'),
            lines: allLines,
            totalSize: fileSize,
            linesCount: allLines.length,
            hasMore: false
        };
    }

    // 对于指定行数，使用分块读取策略
    let readSize = Math.min(lines * 150, fileSize); // 增加每行估算字节数
    let buffer = Buffer.alloc(readSize);
    const fd = await fs.open(path, 'r');
    let { bytesRead } = await fd.read(buffer, 0, readSize, 0);

    let content = buffer.subarray(0, bytesRead).toString('utf8');
    let allLines = content.split('\n').filter((line) => line.length > 0);

    // 如果读取的行数不够且还有更多内容，继续读取
    while (allLines.length < lines && bytesRead < fileSize) {
        const additionalSize = Math.min(fileSize - bytesRead, 1024 * 1024); // 每次最多读取1MB
        const additionalBuffer = Buffer.alloc(additionalSize);
        const { bytesRead: additionalBytesRead } = await fd.read(
            additionalBuffer,
            0,
            additionalSize,
            bytesRead
        );

        if (additionalBytesRead === 0) break;

        const additionalContent = additionalBuffer
            .subarray(0, additionalBytesRead)
            .toString('utf8');
        content += additionalContent;
        bytesRead += additionalBytesRead;

        allLines = content.split('\n').filter((line) => line.length > 0);
    }

    await fd.close();

    // 确保不会在行中间截断
    if (bytesRead < fileSize) {
        const lastNewlineIndex = content.lastIndexOf('\n');
        if (lastNewlineIndex > -1) {
            content = content.substring(0, lastNewlineIndex + 1);
            allLines = content.split('\n').filter((line) => line.length > 0);
        }
    }

    const headLines = allLines.slice(0, lines);
    const hasMore = allLines.length > lines || bytesRead < fileSize;

    return {
        content: headLines.join('\n'),
        lines: headLines,
        totalSize: fileSize,
        linesCount: headLines.length,
        hasMore
    };
});

// 获取文件尾部内容（用于初始加载）
ipcMain.handle('read_file_tail', async (_, options: { path: string; lines?: number }) => {
    const { path, lines = 1000 } = options;
    const stats = await fs.stat(path);
    const fileSize = stats.size;

    if (fileSize === 0) {
        return { content: '', lines: [], totalSize: 0 };
    }

    // 估算需要读取的字节数（假设平均每行100字符）
    const estimatedBytes = Math.min(lines * 100, fileSize);
    const startOffset = Math.max(0, fileSize - estimatedBytes);

    const buffer = Buffer.alloc(estimatedBytes);
    const fd = await fs.open(path, 'r');
    const { bytesRead } = await fd.read(buffer, 0, estimatedBytes, startOffset);
    await fd.close();

    let content = buffer.subarray(0, bytesRead).toString('utf8');

    // 如果不是从文件开始读取，跳过第一个不完整的行
    if (startOffset > 0) {
        const firstNewlineIndex = content.indexOf('\n');
        if (firstNewlineIndex > -1) {
            content = content.substring(firstNewlineIndex + 1);
        }
    }

    const allLines = content.split('\n').filter((line) => line.length > 0);
    const tailLines = allLines.slice(-lines);

    return {
        content: tailLines.join('\n'),
        lines: tailLines,
        totalSize: fileSize,
        linesCount: tailLines.length
    };
});

// 检查端口是否被占用
ipcMain.handle('check_port_occupied', async (_, port: number) => {
    return new Promise((resolve) => {
        const server = net.createServer();

        server.listen(port, () => {
            server.once('close', () => {
                resolve({
                    success: true,
                    occupied: false,
                    message: `端口 ${port} 可用`
                });
            });
            server.close();
        });

        server.on('error', (err: any) => {
            if (err.code === 'EADDRINUSE') {
                resolve({
                    success: true,
                    occupied: true,
                    message: `端口 ${port} 已被占用`
                });
            } else {
                resolve({
                    success: false,
                    occupied: false,
                    message: `检查端口 ${port} 时发生错误: ${err.message}`
                });
            }
        });
    });
});

// 全局变量用于管理 JAR 服务进程
let jarServiceProcess: any = null;

// 启动 JAR 服务
ipcMain.handle(
    'start_jar_service',
    async (_, options: { jdkPath: string; jarPath: string; port?: number; active?: string }) => {
        try {
            const { jdkPath, jarPath } = options;

            // 如果已有进程在运行，先停止
            if (jarServiceProcess) {
                try {
                    jarServiceProcess.kill();
                    jarServiceProcess = null;
                } catch (error) {
                    console.warn('Stop Old Server Failed:', error);
                }
            }

            // 构建 Java 可执行文件路径
            const javaExecutable = path.join(jdkPath, 'bin', 'java.exe');

            // 检查 Java 可执行文件是否存在
            try {
                await fs.access(javaExecutable);
            } catch {
                return {
                    success: false,
                    message: `Java 可执行文件不存在: ${javaExecutable}`
                };
            }

            // 获取 JAR 文件名（不含路径）
            const jarFileName = path.basename(jarPath);

            const port = options.port || 10001;
            const active = options.active || 'package';

            // JVM 参数
            const jvmArgs = [
                '-server',
                '-Dserver.port=' + port,
                '-Xmx2703m',
                '-Xms2703m',
                '-Xmn1540m',
                '-Xss256k',
                '-XX:MetaspaceSize=256m',
                '-XX:MaxMetaspaceSize=512m',
                '-XX:+UseG1GC',
                '-XX:CICompilerCount=3',
                '-XX:ParallelGCThreads=4',
                '-XX:G1ConcRefinementThreads=2',
                '-XX:ConcGCThreads=2',
                '-XX:MaxHeapFreeRatio=40',
                '-XX:InitiatingHeapOccupancyPercent=45',
                '-XX:MaxDirectMemorySize=256m',
                '-XX:-ShrinkHeapInSteps',
                '-XX:+SegmentedCodeCache',
                '-verbose:gc',
                '-XX:+PrintCommandLineFlags',
                '-XX:+ExplicitGCInvokesConcurrent',
                '-XX:+HeapDumpOnOutOfMemoryError',
                '-XX:HeapDumpPath=./logs',
                '-jar',
                '-Dspring.profiles.active=' + active,
                jarPath
            ];

            // 构建完整命令
            const command = `"${javaExecutable}" ${jvmArgs.join(' ')}`;

            console.log('exec jar command:', command);

            // 启动进程
            const { spawn } = require('node:child_process');
            jarServiceProcess = spawn(javaExecutable, jvmArgs, {
                cwd: path.dirname(jarPath),
                stdio: ['ignore', 'pipe', 'pipe'],
                detached: false
            });

            // 监听进程事件
            jarServiceProcess.on('error', (error: any) => {
                console.error('JAR Server Error:', error);
                jarServiceProcess = null;
            });

            jarServiceProcess.on('exit', (code: number, signal: string) => {
                console.log(`JAR Server Exit: ${code}, 信号: ${signal}`);
                jarServiceProcess = null;
            });

            // 监听输出（可选，用于调试）
            jarServiceProcess.stdout?.on('data', (data: Buffer) => {
                console.log('JAR Server Output:', data.toString());
            });

            jarServiceProcess.stderr?.on('data', (data: Buffer) => {
                console.error('JAR Server Error Output:', data.toString());
            });

            return {
                success: true,
                message: '服务启动成功',
                pid: jarServiceProcess.pid
            };
        } catch (error: any) {
            return {
                success: false,
                message: `启动服务失败: ${error.message}`
            };
        }
    }
);

// 停止 JAR 服务
ipcMain.handle('stop_jar_service', async () => {
    try {
        if (!jarServiceProcess) {
            return {
                success: true,
                message: '服务未运行'
            };
        }

        // 尝试优雅关闭
        jarServiceProcess.kill('SIGTERM');

        // 等待一段时间后强制关闭
        setTimeout(() => {
            if (jarServiceProcess) {
                jarServiceProcess.kill('SIGKILL');
                jarServiceProcess = null;
            }
        }, 5000);

        jarServiceProcess = null;

        return {
            success: true,
            message: '服务已停止'
        };
    } catch (error: any) {
        return {
            success: false,
            message: `停止服务失败: ${error.message}`
        };
    }
});

// 检查服务健康状态
ipcMain.handle('check_service_health', async () => {
    try {
        const https = require('node:http');
        console.log('start check:!!!!!');
        return new Promise((resolve) => {
            const req = https.request(
                {
                    hostname: '127.0.0.1',
                    port: 10001,
                    path: '/health/ping',
                    method: 'GET',
                    timeout: 5000
                },
                (res: any) => {
                    if (res.statusCode === 200) {
                        resolve({
                            success: true,
                            message: '服务健康检查通过'
                        });
                    } else {
                        resolve({
                            success: false,
                            message: `服务响应异常，状态码: ${res.statusCode}`
                        });
                    }
                }
            );

            req.on('error', (error: any) => {
                resolve({
                    success: false,
                    message: `健康检查失败: ${error.message}`
                });
            });

            req.on('timeout', () => {
                req.destroy();
                resolve({
                    success: false,
                    message: '健康检查超时'
                });
            });

            req.end();
        });
    } catch (error: any) {
        return {
            success: false,
            message: `健康检查异常: ${error.message}`
        };
    }
});

// 版本检查相关的 IPC 处理函数
ipcMain.handle('fetch_version_info', async (_, versionUrl: string) => {
    return new Promise((resolve, reject) => {
        const url = new URL(versionUrl);
        const client = url.protocol === 'https:' ? https : http;

        // HTTPS 请求选项，忽略证书验证
        const requestOptions = {
            hostname: url.hostname,
            port: url.port,
            path: url.pathname + url.search,
            method: 'GET',
            // 忽略证书验证以解决证书过期问题
            rejectUnauthorized: false
        };

        const req = client.request(requestOptions, (res) => {
            let data = '';

            res.on('data', (chunk) => {
                data += chunk;
            });

            res.on('end', () => {
                try {
                    const response = JSON.parse(data);
                    // 检查新的 API 响应格式
                    if (response.code === 0 && response.success && response.data) {
                        // 处理 createTime 时间戳格式
                        const versionInfo = {
                            ...response.data,
                            createTime: response.data.createTime
                                ? new Date(response.data.createTime).toLocaleString('zh-CN')
                                : ''
                        };

                        resolve({
                            success: true,
                            data: versionInfo
                        });
                    } else {
                        resolve({
                            success: false,
                            message: response.msg || '获取版本信息失败'
                        });
                    }
                } catch (error: any) {
                    resolve({
                        success: false,
                        message: `解析响应数据失败: ${error.message}`
                    });
                }
            });
        });

        req.on('error', (error: any) => {
            resolve({
                success: false,
                message: `请求失败: ${error.message}`
            });
        });

        req.setTimeout(10000, () => {
            req.destroy();
            resolve({
                success: false,
                message: '请求超时'
            });
        });

        req.end();
    });
});

// 获取本地缓存版本
ipcMain.handle('get_cached_version', async () => {
    try {
        const configPath = path.join(os.homedir(), '.yzj-admin', 'version.json');
        const data = await fs.readFile(configPath, 'utf8');
        return {
            success: true,
            data: JSON.parse(data)
        };
    } catch (error: any) {
        return {
            success: false,
            message: `读取缓存版本失败: ${error.message}`
        };
    }
});

// 保存版本信息到本地缓存
ipcMain.handle('save_version_cache', async (_, versionInfo: any) => {
    try {
        const configDir = path.join(os.homedir(), '.yzj-admin');
        const configPath = path.join(configDir, 'version.json');

        // 确保目录存在
        await fs.mkdir(configDir, { recursive: true });

        await fs.writeFile(configPath, JSON.stringify(versionInfo, null, 2));
        return {
            success: true
        };
    } catch (error: any) {
        return {
            success: false,
            message: `保存版本缓存失败: ${error.message}`
        };
    }
});

// 文件下载相关变量
let downloadAbortController: AbortController | null = null;

// 下载文件
ipcMain.handle(
    'download_file',
    async (
        _,
        options: {
            downloadUrl: string;
            savePath: string;
            fileName: string;
        }
    ) => {
        const { downloadUrl, savePath, fileName } = options;
        const fullPath = path.join(savePath, fileName);

        return new Promise((resolve) => {
            try {
                // 创建新的 AbortController
                downloadAbortController = new AbortController();

                const url = new URL(downloadUrl);
                const client = url.protocol === 'https:' ? https : http;

                const req = client.request(url, (res) => {
                    if (res.statusCode !== 200) {
                        resolve({
                            success: false,
                            message: `下载失败，状态码: ${res.statusCode}`
                        });
                        return;
                    }

                    const totalSize = parseInt(res.headers['content-length'] || '0', 10);
                    let downloadedSize = 0;
                    let lastTime = Date.now();
                    let lastDownloaded = 0;

                    const writeStream = require('fs').createWriteStream(fullPath);

                    res.on('data', (chunk) => {
                        if (downloadAbortController?.signal.aborted) {
                            writeStream.destroy();
                            return;
                        }

                        downloadedSize += chunk.length;
                        writeStream.write(chunk);

                        // 计算下载速度和进度
                        const now = Date.now();
                        const timeDiff = now - lastTime;

                        if (timeDiff >= 1000) {
                            // 每秒更新一次
                            const speed = (downloadedSize - lastDownloaded) / (timeDiff / 1000);
                            const progress = totalSize > 0 ? (downloadedSize / totalSize) * 100 : 0;

                            // 发送进度更新到渲染进程
                            win?.webContents.send('download-progress', {
                                progress: Math.round(progress * 100) / 100,
                                downloadedSize,
                                totalSize,
                                speed: Math.round(speed)
                            });

                            lastTime = now;
                            lastDownloaded = downloadedSize;
                        }
                    });

                    res.on('end', () => {
                        writeStream.end();
                        if (!downloadAbortController?.signal.aborted) {
                            resolve({
                                success: true,
                                filePath: fullPath
                            });
                        }
                    });

                    writeStream.on('error', (error: any) => {
                        resolve({
                            success: false,
                            message: `写入文件失败: ${error.message}`
                        });
                    });
                });

                req.on('error', (error: any) => {
                    resolve({
                        success: false,
                        message: `下载请求失败: ${error.message}`
                    });
                });

                req.setTimeout(30000, () => {
                    req.destroy();
                    resolve({
                        success: false,
                        message: '下载超时'
                    });
                });

                // 监听取消信号
                downloadAbortController.signal.addEventListener('abort', () => {
                    req.destroy();
                    resolve({
                        success: false,
                        message: '下载已取消'
                    });
                });

                req.end();
            } catch (error: any) {
                resolve({
                    success: false,
                    message: `下载异常: ${error.message}`
                });
            }
        });
    }
);

// 取消下载
ipcMain.handle('cancel_download', async () => {
    if (downloadAbortController) {
        downloadAbortController.abort();
        downloadAbortController = null;
        return { success: true };
    }
    return { success: false, message: '没有正在进行的下载任务' };
});

// 检查文件是否存在
ipcMain.handle('check_file_exists', async (_, filePath: string) => {
    try {
        await fs.access(filePath);
        return { success: true, exists: true };
    } catch {
        return { success: true, exists: false };
    }
});

// 选择下载路径
ipcMain.handle('select_download_path', async () => {
    try {
        const result = await dialog.showOpenDialog(win!, {
            properties: ['openDirectory'],
            title: '选择下载路径'
        });

        if (!result.canceled && result.filePaths.length > 0) {
            return {
                success: true,
                path: result.filePaths[0]
            };
        }

        return {
            success: false,
            message: '用户取消选择'
        };
    } catch (error: any) {
        return {
            success: false,
            message: `选择路径失败: ${error.message}`
        };
    }
});
